package com.nfit.seckilldemo1.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * ClassName:SeckillService
 * Package:com.nfit.seckilldemo1.service
 * Description
 *
 * @Author L
 * @Create 2025/2/17 19:35
 */
@Service
public class SeckillService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    private static final String STOCK_PREFIX = "seckill:stock:";
    private static final String USER_PREFIX = "seckill:users:";

    /**
     * 预扣Redis库存（Lua脚本保证原子性）
     * @param skuId      商品ID
     * @param quantity   购买数量
     * @return true - 扣减成功，false - 库存不足
     */
    public boolean preReduceStock(Long skuId, Integer quantity) {
        String stockKey = STOCK_PREFIX + skuId;
        // 使用Lua脚本保证原子性
        String luaScript =
                "if (redis.call('exists', KEYS[1]) == 1) then " +
                        "    local stock = tonumber(redis.call('get', KEYS[1])); " +
                        "    if (stock >= tonumber(ARGV[1])) then " +
                        "        redis.call('decrby', KEYS[1], ARGV[1]); " +
                        "        return 1; " +
                        "    end; " +
                        "    return 0; " +
                        "end; " +
                        "return -1;";
        RedisScript<Long> script = new DefaultRedisScript<>(luaScript, Long.class);
        Long result = redisTemplate.execute(script, Collections.singletonList(stockKey), quantity);
        return result != null && result == 1;
    }

    /**
     * 检查用户是否购买过该商品
     */
    public boolean isUserPurchased(Long userId, Long skuId) {
        return Boolean.TRUE.equals(
                redisTemplate.opsForSet().isMember("seckill:users:" + skuId, userId.toString())
        );
    }
}
